# SteppingIterator.java

    package org.codefilarete.tool.collection;

    import java.util.Iterator;

    /**
     * {@link Iterator} that invokes a method every N iterations
     * {@link #hasNext()} triggers the invocation to {@link #onStep()} to mimic a while(hasNext) or a foreach : {@link #next()} doesn't do it because
     * it seems to be one iteration too late in this context of usage.
     * {@link #onStep()} is also invoked when {@link #hasNext()} returns false (except if it is the very first call) to treat the remaining objects.
     *
     * @author Guillaume Mary
     * @see #onStep()
     */
    public abstract class SteppingIterator<E> implements Iterator<E> {

    	private final Iterator<? extends E> delegate;
    	private long stepCount = 0;
    	private final long stepSize;

    	public SteppingIterator(Iterable<? extends E> delegate, long stepSize) {
    		this(delegate.iterator(), stepSize);
    	}

    	public SteppingIterator(Iterator<? extends E> delegate, long stepSize) {
    		this.delegate = delegate;
    		this.stepSize = stepSize;
    	}

    	@Override
    	public boolean hasNext() {
    		boolean hasNext = delegate.hasNext();
    		if (	// step reached
    				stepCount == stepSize
    				// or has remainings (end reached and not started)
    				|| (!hasNext && stepCount != 0)) {
    			onStep();
    			stepCount = 0;
    		}
    		return hasNext;
    	}

    	@Override
    	public E next() {
    		stepCount++;
    		return delegate.next();
    	}

    	public long getStepSize() {
    		return stepSize;
    	}

    	public long getStepCount() {
    		return stepCount;
    	}

    	/**
    	 * To be overridden to perform some action when steps are reached and remaining items are processed (on {@link #hasNext()} returns false)
    	 */
    	protected abstract void onStep();

    	@Override
    	public void remove() {
    		delegate.remove();
    	}
    }